package tt.dz.service.imp.middleware;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import tt.dz.dao.base.BaseDao;
import tt.dz.dao.ext.dic.OmsDicForwardSrvInfoDao;
import tt.dz.dao.ext.dic.OmsPubParamDao;
import tt.dz.dao.ext.system.OmsOperationSpListDao;
import tt.dz.entity.base.OmsPubParam;
import tt.dz.service.middleware.EncapsulationService;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;
import tt.dz.util.serialGenerater;
//本接口只做数据封装，不做数据发送   静态对象常量0000000000000000
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class Ev3c2EncapsulationServiceImpl implements EncapsulationService{

	@Resource
	OmsPubParamDao omsPubParamDao;
//	@Resource(name = "omsOperationSpListDao")
//	OmsOperationSpListDao omsOperationSpListDao;
//	@Autowired
//	OmsOperationSpListDao omsOperationSpListDao;
//	@SuppressWarnings("rawtypes")
//	@Autowired
//	BaseDao baseDao;
	@Autowired
	OmsDicForwardSrvInfoDao omsDicForwardSrvInfoDao;	
//	@Resource(name = "dzTcpShortConnectionClient")
//	SendMsg dzTcpShortConnectionClient;
	
	private  Log log = LogFactory.getLog(Ev3c2EncapsulationServiceImpl.class); 
	
	String ev3c_msg,ev3c_msgBody,ev3c_msgHeader,ev3c_frameCode,chargerId,protocol_version;
	long timoutMillisecond = 1000*60*5;
	@Override
	public String loginReturn(Map<String, String> map) {
		ev3c_frameCode ="A2";
		chargerId = map.get("chargerId");
		String port_str = String.valueOf(Integer.toHexString(Integer.valueOf(map.get("port"))));
		ev3c_msgBody = map.get("communicationNo")+chargerId+"0000000000000000"+map.get("protocol_version")+
				StringUtil.ip2HexStr(map.get("source_ip"))+port_str.substring(2, 4)+port_str.substring(0, 2);
		ev3c_msgHeader = "68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+map.get("communicationNo")+chargerId+ev3c_frameCode+map.get("serialNumber");
		return ev3c_msgHeader + ev3c_msgBody;	
	}

	@Override
	public String logoutReturn(Map<String, String> map) {
		ev3c_frameCode ="A4";
		chargerId = map.get("chargerId");
		String data = map.get("data");
		ev3c_msgHeader = "680000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36);
		return ev3c_msgHeader;
	}
	@Override
	public String startCharge(Map<String, String> map) {
		ev3c_frameCode ="10";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101StartCharge(map);
				break;
			case "0102":
				ev3c_msg = ev3c0102StartCharge(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103StartCharge(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}
	@Override
	public String startChargeReturn(Map<String, String> map) {
		ev3c_frameCode ="56";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				ev3c_msg = ev3c0102StartChargeReturn(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103StartChargeReturn(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0102StartChargeReturn(Map<String, String> map) {
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+ data.substring(36, 50);
	}

	private String ev3c0103StartChargeReturn(Map<String, String> map) {
		return ev3c0102StartChargeReturn(map);
	}

	@Override
	public String stopCharge(Map<String, String> map) {
		ev3c_frameCode ="12";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101StopCharge(map);
				break;
			case "0102":
				ev3c_msg = ev3c0102StopCharge(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103StopCharge(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101StopCharge(Map<String, String> map) {
		String chargerId = map.get("chargerId");
		String userCard= map.get("userCard");
		String port= map.get("port");
		String responseMsgHeader,responseMsgBody; 
		String code_type = "12";
//		String dec_port = "01";//为什么是01不是00
		String control_type = "04";
		responseMsgBody = port+control_type+userCard;
		responseMsgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+code_type+StringUtil.now14time();
		return responseMsgHeader+responseMsgBody;
	}

	private String ev3c0102StopCharge(Map<String, String> map) {
		return ev3c0101StopCharge(map);
	}

	private String ev3c0103StopCharge(Map<String, String> map) {
		return ev3c0101StopCharge(map);
	}

	@Override
	public String stopChargeReturn(Map<String, String> map) {
		ev3c_frameCode ="57";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				ev3c_msg = ev3c0102StopChargeReturn(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103StopChargeReturn(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0102StopChargeReturn(Map<String, String> map) {
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+ data.substring(36, 50);

	}

	private String ev3c0103StopChargeReturn(Map<String, String> map) {
		return ev3c0102StopChargeReturn(map);
	}

	@Override
	public String bespeak(Map<String, String> map) {
		ev3c_frameCode ="14";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101Bespeak(map);
				break;
			case "0102":
				ev3c_msg = ev3c0102Bespeak(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103Bespeak(map);
				break;
			case "0201":
				ev3c_msg = ev3c0201Bespeak(map);
				break;	
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0201Bespeak(Map<String, String> map) {
		
		return null;
	}

	private String ev3c0101Bespeak(Map<String, String> map) {
		String chargerId, portNo, userCard;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		userCard = map.get("userCard");
		String msgBody = portNo + userCard;// 00表示A口，01表示B口
		String msgHeader = "68" + StringUtil.ev3cMsgBody16Length(ev3c_msgBody) + "01" + "000000" + "0001"
				+ chargerId + "14" + StringUtil.now14time();
//		StringUtil.sendSocket(msgHeader + msgBody);// TODO 等周天接口
//		String ev3c0101BespeakReturn = dzNettyClient.send(msgHeader + msgBody, timoutMillisecond);
//		iSendMsg.sendAndWait(msg, timoutMillisecond);
		return msgHeader + msgBody;
	}

	private String ev3c0102Bespeak(Map<String, String> map) {
		return ev3c0101Bespeak(map);
	}

	private String ev3c0103Bespeak(Map<String, String> map) {
		String chargerId, portNo, userCard, bespeakMinute;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		userCard = map.get("userCard");
		bespeakMinute = map.get("bespeakMinute");//单位：分  例：预约2小时30分钟   bespeakMinute = 150   实际传输数据为：0x96 0x00
		String key = chargerId+portNo+userCard;
		RedisClient.delByKey(key);
		RedisClient.putString(key, bespeakMinute);
		int bespeakMinute_int = Integer.valueOf(bespeakMinute);
		RedisClient.expire(key, bespeakMinute_int * 60 + 600);//过期时间在原时间基础上加10分钟
		ev3c_msgBody = portNo + userCard + StringUtil.float10to16ByParamDesc(bespeakMinute, 1, 4);// 00表示A口，01表示B口
		ev3c_msgHeader = "68" + StringUtil.ev3cMsgBody16Length(ev3c_msgBody) + "01" + "000000" + "0001"
				+ chargerId + "14" + StringUtil.now14time();
//		StringUtil.sendSocket(msgHeader + msgBody);// TODO 等周天接口
		return ev3c_msgHeader + ev3c_msgBody;
	}	
	
	
	@Override
	public String cancelBespeak(Map<String, String> map) {
		ev3c_frameCode ="16";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101CancelBespeak(map);
				break;
			case "0102":
				ev3c_msg = ev3c0102CancelBespeak(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103CancelBespeak(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101CancelBespeak(Map<String, String> map) {
		String chargerId, portNo, userCard;
		chargerId = map.get("chargerId");
		portNo = map.get("portNo");
		userCard = map.get("userCard");
		ev3c_msgBody = portNo + userCard;// 00表示A口，01表示B口
		ev3c_msgHeader = "68" + StringUtil.ev3cMsgBody16Length(ev3c_msgBody) + "01" + "000000" + "0001"
				+ chargerId + "16" + StringUtil.now14time();
//		StringUtil.sendSocket(msgHeader + msgBody);// TODO 等周天接口
		return ev3c_msgHeader + ev3c_msgBody;
	}

	private String ev3c0102CancelBespeak(Map<String, String> map) {
		return ev3c0101CancelBespeak(map);
	}

	private String ev3c0103CancelBespeak(Map<String, String> map) {
		return ev3c0101CancelBespeak(map);
	}		
	
	
	@Override
	public String cancelBespeakReturn(Map<String, String> map) {
		ev3c_frameCode ="58";
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				ev3c_msg = "680000"+data.substring(6, 34)+ev3c_frameCode+ data.substring(36, 50);
				break;
			case "0103":
				ev3c_msg = "680000"+data.substring(6, 34)+ev3c_frameCode+ data.substring(36, 50);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	@Override
	public String restartCharger(Map<String, String> map) {
		protocol_version = map.get("protocol_version");
		chargerId = map.get("chargerId");
		ev3c_frameCode = "18";
		ev3c_msgBody ="";
		ev3c_msgHeader = "68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		//TODO 发送到中间件 等周天接口
		return ev3c_msgHeader;
	}

	@Override
	public String updateFirmware(Map<String, String> map) {
		ev3c_frameCode ="1A";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				break;
			case "0103":
				ev3c_msg = ev3c0103UpdateFirmware(map);
//				ev3c_msg = data.substring(0, 34)+ev3c_frameCode+ data.substring(36, 50);
				break;
			default:
				break;
		}
		return ev3c_msg;		
	}

	private String ev3c0103UpdateFirmware(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String source_ip =map.get("source_ip");//BIN码
		String source_ip_bin = StringUtil.ip2HexStr(source_ip);
		String source_port =map.get("source_port");//BIN码倒序
		String source_port_bin =StringUtil.float10to16ByParamDesc(source_port, 1, 4);
		String ascii_software =map.get("ascii_software");
		String download_time =map.get("download_time");//
		String retry_interval_second =map.get("source_ip");//倒序  *重试间隔（秒）BIN码 例：间隔2秒，实际传输数据为：0x02
		String retry_interval_second_bin =StringUtil.float10to16ByParamDesc(retry_interval_second, 1, 2);
		String retry_interval_times =map.get("source_ip");//倒序  超过重试超时次数均未收到回复，退出升级过程，上报升级结果为失败。
		String retry_interval_times_bin =StringUtil.float10to16ByParamDesc(retry_interval_times, 1, 2);
		ev3c_msgBody =source_ip_bin + source_port_bin + ascii_software + download_time + retry_interval_second_bin + retry_interval_times_bin;
		ev3c_msgHeader = "68"+ StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String findHardwareServerIp(Map<String, String> map) {
		ev3c_frameCode ="30";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101FindHardwareServerIp(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101FindHardwareServerIp(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101FindHardwareServerIp(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101FindHardwareServerIp(Map<String, String> map) {
		chargerId = map.get("chargerId");
		ev3c_msgHeader = "68"+ StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader;
	}

	@Override
	public String setHardwareServerIp(Map<String, String> map) {
		ev3c_frameCode ="32";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101SetHardwareServerIp(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101SetHardwareServerIp(map);
				break;
			case "0103":
				ev3c_msg = ev3c0103SetHardwareServerIp(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101SetHardwareServerIp(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String ev3c_communicationNo = map.get("communicationNo");
		String main_hardware_ip =map.get("main_hardware_ip");
		main_hardware_ip = StringUtil.ip2HexStr(main_hardware_ip);
		String main_port =map.get("main_port");
		main_port =StringUtil.float10to16ByParamDesc(main_port, 1, 4);
		String back_headware_ip =map.get("ipaddress2");
		back_headware_ip = StringUtil.ip2HexStr(back_headware_ip);
		String back_port =map.get("back_port");
		back_port = StringUtil.float10to16ByParamDesc(back_port, 1, 4);
		ev3c_msgBody ="00"+StringUtil.now14time()+main_hardware_ip+main_port+back_headware_ip+back_port;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+ev3c_communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);//TODO 等周天接口
		return ev3c_msgHeader+ev3c_msgBody;
	}

	private String ev3c0103SetHardwareServerIp(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String ev3c_communicationNo = map.get("communicationNo");
		String main_hardware_ip =map.get("main_hardware_ip");
		main_hardware_ip = StringUtil.ip2HexStr(main_hardware_ip);
		String main_port =map.get("main_port");
		main_port =StringUtil.float10to16ByParamDesc(main_port, 1, 4);
		String back_headware_ip =map.get("ipaddress2");
		back_headware_ip = StringUtil.ip2HexStr(back_headware_ip);
		String back_port =map.get("back_port");
		back_port = StringUtil.float10to16ByParamDesc(back_port, 1, 4);
		String is_re_regist =map.get("is_re_regist");//0x00: 不需重新注册，使用已有设备地址直接在新服务器签到。
											   //0x01：需要重置“是否已注册”标记，切换到新服务器后重新注册获取设备地址。
		String is_re_regist_bin =StringUtil.float10to16ByParamDesc(is_re_regist, 1, 2);
		ev3c_msgBody ="00"+StringUtil.now14time()+main_hardware_ip+main_port+back_headware_ip+back_port+is_re_regist_bin;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+ev3c_communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);//TODO 等周天接口
		return ev3c_msgHeader+ev3c_msgBody;
	}

	@Override
	public String setTime(Map<String, String> map) {
		ev3c_frameCode ="34";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101SetTime(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101SetTime(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101SetTime(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101SetTime(Map<String, String> map) {
		chargerId = map.get("chargerId");
		ev3c_msgBody = StringUtil.sixteen2time14(null);
		ev3c_msgHeader = "68" + StringUtil.ev3cMsgBody16Length(ev3c_msgBody) + "01" + "000000" + "0001" + chargerId + ev3c_frameCode + StringUtil.now14time();
		return  ev3c_msgHeader+ev3c_msgBody; 
	}

	@Override
	public String findRate(Map<String, String> map) {
		ev3c_frameCode ="36";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101FindRate(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101FindRate(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101FindRate(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101FindRate(Map<String, String> map) {
		chargerId = map.get("chargerId");
		ev3c_msgHeader ="68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader;
	}

	@Override
	public String setRate(Map<String, String> map) {
		ev3c_frameCode ="38";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101SetRate(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101SetRate(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101SetRate(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101SetRate(Map<String, String> map) {
//		String data = request.getParameter("data");
		String chargerId = map.get("chargerId");
		String rate1 = map.get("rate1");
		String rate2 = map.get("rate2");
		String rate3 = map.get("rate3");
		String rate4 = map.get("rate4");
		String service_fee = map.get("service_fee");
		String timeRate = map.get("timeRate");
//		timeRate = "010203040102030401020304010203040101010101010101010101010101010101010103010101010101040104010203";
	    // 数据放大100倍，然后转化成16进制
		String rate1_100_16 = StringUtil.float10to16ByParamDesc(rate1,100,4);
		String rate2_100_16 = StringUtil.float10to16ByParamDesc(rate2,100,4);
		String rate3_100_16 = StringUtil.float10to16ByParamDesc(rate3,100,4);
		String rate4_100_16 = StringUtil.float10to16ByParamDesc(rate4,100,4);
		String service_fee_100_16 = StringUtil.float10to16ByParamDesc(service_fee,100,4);
		ev3c_msgBody = rate1_100_16+rate2_100_16+rate3_100_16+rate4_100_16+service_fee_100_16+timeRate;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String setQrCode(Map<String, String> map) {
		ev3c_frameCode ="77";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101SetQrCode(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101SetQrCode(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101SetQrCode(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101SetQrCode(Map<String, String> map) {
		String chargerId = map.get("chargerId");
		ev3c_msgBody = map.get("qrCode");
		ev3c_msgHeader = "68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);
		return  ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String findWhiteList(Map<String, String> map) {
		ev3c_frameCode ="3A";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				ev3c_msg = ev3c0103FindWhiteList(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0103FindWhiteList(Map<String, String> map) {
		chargerId = map.get("chargerId");
		ev3c_msgHeader ="68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader;
	}

	@Override
	public String setWhiteList(Map<String, String> map) {
		ev3c_frameCode ="3C";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0103":
				ev3c_msg = ev3c0103SetWhiteList(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0103SetWhiteList(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String whiteList = map.get("whiteList");
		String key = chargerId+"_set_whiteList";
		StringUtil.removeNullValue(map);
		RedisClient.putMap(key, map);
		StringBuilder sb = new StringBuilder("");//逗号分隔
		if(StringUtil.isNotBlank(whiteList)){
			String[] list = whiteList.split(",");
			for(String str : list){
				sb.append(str);
			}
			ev3c_msgBody = StringUtil.float10to16ByParamDesc(String.valueOf(list.length), 1, 2)+sb.toString();
		}else{
			ev3c_msgBody ="0000";
		}
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String setParam(Map<String, String> map) {
		ev3c_frameCode ="3E";
		protocol_version = map.get("protocol_version");
		String ev3c_msg = "";
		switch (protocol_version) {
			case "0103":
				ev3c_msg = ev3c0103SetParam(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	//  为什么是2位     *参数数据长度	BIN码	2		操作类型为0x00查询时，填0x00表示无参数数据。
	private String ev3c0103SetParam(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String control_type = map.get("control_type");
		String param_no = map.get("param_no");
		String param_length = "0000";
		String param = "";
		String param_bin_desc = "";
		if(control_type.equals("01")){
			switch(param_no){
				case "00":
					break;
				case "01":
					param_length = "0300";
					param =  map.get("param");
					param_bin_desc = StringUtil.float10to16ByParamDesc(param, 100, 6);
					break;
				case "02":
					param_length = "0300";
					param =  map.get("param");
					param_bin_desc = StringUtil.float10to16ByParamDesc(param, 100, 6);
					break;
				case "03":
					param_length = "0300";
					param =  map.get("param");
					param_bin_desc = StringUtil.float10to16ByParamDesc(param, 100, 6);
					break;
				case "04":
					param_length = "0100";
					param =  map.get("param");
					param_bin_desc = StringUtil.float10to16ByParamDesc(param, 100, 2);
					break;
				default:
					break;
			}
		}
		ev3c_msgBody = control_type + param_no + param_length + param_bin_desc;
		ev3c_msgHeader = "68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String requestPayByCardReturn(Map<String, String> map) {
		ev3c_frameCode ="76";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101RequestPayByCardReturn(map);
				break;
			case "0102":
				ev3c_msg = ev3c0102RequestPayByCardReturn(map);
				break;
			case "0103":
				ev3c_msg = ev3c0102RequestPayByCardReturn(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	
	private String ev3c0101RequestPayByCardReturn(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String returnCode =map.get("returnCode");
		String portNo = "00";
		String userCard = map.get("userCard");
		ev3c_msgBody = portNo+userCard+returnCode;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	private String ev3c0102RequestPayByCardReturn(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String returnCode =map.get("returnCode");
		String portNo = map.get("portNo");
		String userCard = map.get("userCard");
		ev3c_msgBody = portNo+userCard+returnCode;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	private String ev3c0101StartCharge(Map<String, String> map) {
		String userCard = map.get("userCard"); 
		//信息头
		String chargerId = map.get("chargerId"); 
//		msgBody = "01040000000000000000"+userCard;
		ev3c_msgBody = "00040000000000000000"+userCard;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	private String ev3c0102StartCharge(Map<String, String> map) {
		return ev3c0101StartCharge(map);
	}

	private String ev3c0103StartCharge(Map<String, String> map) {
		//信息体
		String portNo = map.get("portNo"); //00表示A口，01表示B口……
		if(StringUtil.isBlank(portNo)){
			portNo ="00";
		}
		String controlType = map.get("controlType");  //控制类型见下表对应数据，如0x04为即时开启/BMS充电/自动充满方式
		if(StringUtil.isBlank(controlType)){
			controlType ="04";
		}
		String openRestrictedData = map.get("openRestrictedData");  
		if(StringUtil.isBlank(openRestrictedData)){
			openRestrictedData ="00000000";
		}else{
			int param = 1;
			if(controlType.endsWith("1")){
				param = 100;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}else if(controlType.endsWith("2")){
				param = 1;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}else if(controlType.endsWith("3")){
				param = 100;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}
		}
		String startTime = map.get("startTime");
		if(StringUtil.isBlank(startTime)){
			startTime ="00000000";
		}
		String userCard = map.get("userCard"); 
		String charging_data_upload_interval = map.get("charging_data_upload_interval"); 
		String battery_details_upload_interval = map.get("battery_details_upload_interval"); 
		//信息头
		String chargerId = map.get("chargerId"); 
		String communicationNo = map.get("communicationNo"); 
		if(StringUtil.isBlank(communicationNo)){
			communicationNo ="0001";
		}
		if((!StringUtil.isNumeric(charging_data_upload_interval))||(!StringUtil.isNumeric(battery_details_upload_interval))){//如果充电数据上传间隔或电池详情上传间隔没有赋值，就从数据库中取出默认值
			List<OmsPubParam> list_pubParam  = omsPubParamDao.findListByCondition(new OmsPubParam(), " where param_name in ('charging_data_upload_interval','battery_details_upload_interval')");
			for(OmsPubParam omsPubParam : list_pubParam){
				if(omsPubParam.getParam_name().equals("charging_data_upload_interval")){
					charging_data_upload_interval = omsPubParam.getParam_value();
				}
				if(omsPubParam.getParam_name().equals("battery_details_upload_interval")){
					battery_details_upload_interval = omsPubParam.getParam_value();
				}
			}
		}
		//充电数据上传间隔和电池详情上传间隔放入redis中，生命时长为XXX秒
		Map<String, String> hashMap = new HashMap<String, String>();
		hashMap.put("charging_data_upload_interval", charging_data_upload_interval);
		hashMap.put("battery_details_upload_interval", battery_details_upload_interval);
		String key = chargerId+"_upload_interval";
		RedisClient.putMap(key, hashMap);
		RedisClient.expire(key, 60*60*24);//24小时
		ev3c_msgBody = portNo+controlType+openRestrictedData+startTime+userCard;
//				ev3c_msgBody = "00040000000000000000"+userCard;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBody16Length(ev3c_msgBody)+"01"+"000000"+communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader + ev3c_msgBody;
	}

	@Override
	public String uploadHeartReturn(Map<String, String> map) {
		ev3c_frameCode ="52";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101UploadHeartReturn(map);
				break;
			case "0102":
				ev3c_msg = ev3c0101UploadHeartReturn(map);
				break;
			case "0103":
				ev3c_msg = ev3c0101UploadHeartReturn(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101UploadHeartReturn(Map<String, String> map) {
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36, 50);
	}


	@Override
	//封装类，报文体为空
	public String uploadChangeReturn(Map<String, String> map) {
		String returnMsgBody  = "";
			String msg = generateEv3c2ReturnMsg(returnMsgBody,map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), 
					map.get("portNo"),map.get("msgResponseCode"), map.get("communicationNo"), map.get("encryption"), map.get("chargerSerialNumber"));
			return msg;
	}

	private String ev3c0101UploadChangeReturn(Map<String, String> map) {
//		1 所有String data = map.get("data"); 有问题，要加帧类型
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36, 50);
	}

	@Override
	public String uploadFirmwareStatusReturn(Map<String, String> map) {
		ev3c_frameCode ="5B";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				break;
			case "0103":
				ev3c_msg = ev3c0103UploadFirmwareStatusReturn(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0103UploadFirmwareStatusReturn(Map<String, String> map) {
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36, 50);
	}

	@Override
	public String uploadBillReturn(Map<String, String> map) {
		//TODO 
		return null;
	}

	private String ev3c0101UploadBillReturn(Map<String, String> map) {
		String data = map.get("data");
		return "680000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36, 50);
	}

	@Override
	public String summon(Map<String, String> map) {
		ev3c_frameCode ="71";
		protocol_version = map.get("protocol_version");
		switch (protocol_version) {
			case "0101":
				ev3c_msg = ev3c0101Summon(map);
				break;
			default:
				break;
		}
		return ev3c_msg;
	}

	private String ev3c0101Summon(Map<String, String> map) {
		//信息头
		String chargerId = map.get("chargerId"); 
//		msgBody = "01040000000000000000"+userCard;
		ev3c_msgHeader ="68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return ev3c_msgHeader;
	}

	@Override
	public String chargerRegister(Map<String, String> map)
	{
		String returnMsgBody = map.get("chargerId");

		log.info(map);
		String msg = generateEv3c2ReturnMsgWithoutDataHeader(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"),
				map.get("communicationNo"), map.get("encryption"), map.get("chargerSerialNumber"));
		//&ip="+source_ip+"&port="+source_port+"&fd="+fd
		//注册报文做特殊处理
		msg = MessageFormat.format("{0}&ip={1}&port={2}&fd={3}", msg, map.get("source_ip"), map.get("source_port"), map.get("fd"));
		int whole_length = msg.length() + 9;
		msg = MessageFormat.format("data={0}{1}", String.format("%04d", whole_length), msg);
		log.info(msg);
		return msg;

	}
	//电桩上传：25*2=50,主动上报报文头与1.X版本一致    服务器 返回报文头 为 37*2 =74
	//服务器主动下发报文头：23*2 = 46 ，电桩回复报文头 35*2 =70
	
	//Ev3c 2.0协议从oms发起的报文,封装待发送报文
	public String generateEv3c2SendMsg(String sendMsgBody, String frameCode, String chargerId, String chargerType, String portNo, String encryption,String communicationNo)
	{
		try {
			String sendMsgHeader, msg;
			//生成报文头
			String beginChar = "68";
			String msgBodylenBin = StringUtil.ev3cMsgBodyBin(sendMsgBody);
			String oms_msg_charge_jrnl = serialGenerater.generateSerialNo();
			log.info("msgBodylenBin = "+msgBodylenBin);
			log.info("oms_msg_charge_jrnl = "+oms_msg_charge_jrnl);
			
			//查询  充电运营服务商表 原名叫oms_oper_merchant，新名称叫oms_operation_splist
//			log.info("omsOperationSpListDao = "+omsOperationSpListDao);
//			log.info("baseDao = "+baseDao);
//			log.info("omsOperationSpListDao = "+omsOperationSpListDao);
//			String condition = " where oper_merchant_id in ( select oper_merchant_id from oms_station where " + " station_id = (select station_id from oms_charger where charger_id = '" + chargerId + "' ))";
//			OmsOperationSpList omsOperMerchant = omsOperationSpListDao.findOneExampleByCondition(new OmsOperationSpList(), condition);
//			OmsOperationSpList omsOperMerchant = (OmsOperationSpList) omsOperationSpListDao.findOneExampleByCondition(new OmsOperationSpList(), condition);
//			log.info(omsOperMerchant.toString());
//			if (omsOperMerchant != null && StringUtil.isNotBlank(omsOperMerchant.getCommunication_no()))
//			{
//				communicationNo = omsOperMerchant.getCommunication_no();
//			}
			log.info("beginChar = "+beginChar+" msgBodylenBin = "+msgBodylenBin+" frameCode = "+frameCode+" communicationNo = "+communicationNo+
					" chargerId = "+chargerId+" chargerType = "+chargerType+" portNo = "+portNo+" encryption = "+encryption+" oms_msg_charge_jrnl ="+oms_msg_charge_jrnl);
			sendMsgHeader = beginChar + msgBodylenBin + frameCode + communicationNo + chargerId + chargerType + portNo + encryption + oms_msg_charge_jrnl;
			//生成整个报文
			log.info("sendMsgBody = "+sendMsgBody);
			msg = sendMsgHeader + sendMsgBody;
			if (sendMsgHeader.length() != 50)
			{
				log.error("oms-sendMsgHeader.length != 50");
				return null;
			}
			if (msg.contains("null"))
			{
				log.error("oms-sendMsg include null");
				return null;
			}
			return msg;
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return null;
		}
	}

	//Ev3c 2.0协议从电桩发起的请求报文,封装待回复报文
	public String generateEv3c2ReturnMsg(String returnMsgBody, String frameCode, String chargerId, String chargerType, String portNo, String msgResponseCode,
			String communicationNo, String encryption, String chargerSerialNumber)
	{

		String returnMsgHeader, msg;
		//生成报文头
		String beginChar = "68";
		String msgBodyBin = StringUtil.ev3cMsgBodyBin(returnMsgBody);
		String oms_msg_charge_jrnl = serialGenerater.generateSerialNo();
		returnMsgHeader = beginChar + msgBodyBin + frameCode + communicationNo+ chargerId + chargerType + portNo + msgResponseCode +
				encryption + chargerSerialNumber + oms_msg_charge_jrnl;
		//生成整个报文
		msg = returnMsgHeader + returnMsgBody;
		if (returnMsgHeader.length() != 74)
		{
			log.error("oms-returnMsgHeader.length !=74");
			return null;
		}
		if (msg.contains("null"))
		{
			log.error("oms-returnMsg include null");
			return null;
		}
		int whole_length = msg.length() + 9;
		msg = MessageFormat.format("data={0}{1}", String.format("%04d", whole_length), msg);
		return msg;
	}

	//Ev3c 2.0协议从电桩发起的请求报文,封装待回复报文(没有data=头)
	public String generateEv3c2ReturnMsgWithoutDataHeader(String returnMsgBody, String frameCode, String chargerId, String chargerType, String portNo, String msgResponseCode,
			String communicationNo, String encryption, String chargerSerialNumber)
	{

		String returnMsgHeader, msg;
		//生成报文头
		String beginChar = "68";
		String msgBodyBin = StringUtil.ev3cMsgBodyBin(returnMsgBody);
		String oms_msg_charge_jrnl = serialGenerater.generateSerialNo();
		returnMsgHeader = beginChar + msgBodyBin + frameCode + communicationNo+ chargerId + chargerType + portNo + msgResponseCode +
				encryption + chargerSerialNumber + oms_msg_charge_jrnl;
		//生成整个报文
		msg = returnMsgHeader + returnMsgBody;
		if (returnMsgHeader.length() != 74)
		{
			log.error("oms-returnMsgHeader.length !=74");
			return null;
		}
		if (msg.contains("null"))
		{
			log.error("oms-returnMsg include null");
			return null;
		}
		return msg;
	}


	@Override
	public String chargerUnRegister(Map<String, String> map) {
		String returnMsgBody  = "";
			String msg = generateEv3c2ReturnMsg(returnMsgBody,map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), 
					map.get("portNo"),map.get("msgResponseCode"), map.get("communicationNo"), map.get("encryption"), map.get("chargerSerialNumber"));
			return msg;
	}

	@Override
	public String chargerLogin(Map<String, String> map)
	{
		//TODO 后期做到配置文件中去
		//		心跳频率	BIN码	1	电桩的心跳的上传频率（单位：秒）
		//		心跳重连次数	BIN码	1	服务器不响应时，电桩的心跳重发的次数
		//		报文发送失败时重试间隔	BIN码	1	发送报文后为收到回复，到下一次重试发送报文的间隔时间，例：间隔2秒，实际传输数据为：0x02	单位：秒
		//		报文发送失败后重试超时次数	BIN码	1	超过重试超时次数均未收到回复，判定为断开连接，应重新发起连接并签到。
		//		加密方式	BCD码	1	0x00 不加密码  0x01 DES
		//		0x02 3DES      0x03 AES
		//		通信密钥	BCD码	8+	此部分内容由加密方式决定（默认8个字节）
		log.info("wrap message");
		String heart_rate = "3C";//心跳频率  默认60秒  bin 为3C 
		String heart_try_times = "03";//心跳重连次数	BIN码	1	服务器不响应时，电桩的心跳重发的次数	
		String fail_try_interval = "1E";//30秒  报文发送失败时重试间隔	BIN码	1	发送报文后为收到回复，到下一次重试发送报文的间隔时间，例：间隔2秒，实际传输数据为：0x02	单位：秒
		String fail_try_times = "03";    //报文发送失败后重试超时次数	BIN码	1	超过重试超时次数均未收到回复，判定为断开连接，应重新发起连接并签到。
		String encryption = "00";//		加密方式	BCD码	1	0x00 不加密码  0x01 DES
		String encryption_key = "0000000000000000";// 16个0		通信密钥	BCD码	8+	此部分内容由加密方式决定（默认8个字节）	
		log.info(map);
		String returnMsgBody = heart_rate + heart_try_times + fail_try_interval + fail_try_times + encryption + encryption_key;

		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		log.info(msg);
		return msg;
	}

	@Override
	public String chargerLogout(Map<String, String> map)
	{
		String returnMsgBody = "";
		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		return msg;
	}

	@Override
	public String uploadHeart(Map<String, String> map)
	{
		String returnMsgBody = "";
		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		return msg;
	}

	//封装类，报文体为空
	@Override
	public String uploadBill(Map<String, String> map)
	{
		String returnMsgBody = "";
		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		return msg;
	}

	@Override
	public String uploadChargeData(Map<String, String> map)
	{
		String returnMsgBody = "";
		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		return msg;
	}

	public static String getRandom4int()
	{
		Random ne = new Random();//实例化一个random的对象ne
		int x = ne.nextInt(9999);//为变量赋随机值1000-9999
		return String.format("%04d", x);
	}
	
	/**
	 * 服务器回复突变报文(刷卡)
	 */
	public String uploadSuddenChangeReturn(Map<String, String> map)
	{
		String returnMsgBody = map.get("returnCardState").concat(map.get("returnBalance"));
		String msg = generateEv3c2ReturnMsg(returnMsgBody, map.get("returnFrameCode"), map.get("chargerId"), map.get("chargerType"), map.get("portNo"), map.get("msgResponseCode"), map.get("communicationNo"),
				map.get("encryption"), map.get("chargerSerialNumber"));
		return msg;
	}
}
